/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 */

package com.spsoft.workflow.common.config;

import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
import org.flowable.common.engine.impl.de.odysseus.el.misc.TypeConverter;
import org.flowable.common.engine.impl.de.odysseus.el.misc.TypeConverterImpl;
import org.flowable.spring.SpringProcessEngineConfiguration;
import org.flowable.spring.boot.EngineConfigurationConfigurer;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.AsyncListenableTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;


@Configuration
public class FlowableConfig {
    //    @Resource
//    private DataSource dataSource;
//    @Resource
//    private PlatformTransactionManager transactionManager;
//
//    @Bean
//    public SpringProcessEngineConfiguration getSpringProcessEngineConfiguration() {
//        SpringProcessEngineConfiguration config = new SpringProcessEngineConfiguration();
//        config.setActivityFontName("宋体");
//        config.setAnnotationFontName("宋体");
//        config.setLabelFontName("黑体");
//        config.setDataSource(dataSource);
//        config.setTransactionManager(transactionManager);
//        config.setDisableIdmEngine(true);
//        config.setDatabaseType(ProcessEngineConfigurationImpl.DATABASE_TYPE_MYSQL);
//        config.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
//        config.setDelegateExpressionFieldInjectionMode(DelegateExpressionFieldInjectionMode.MIXED);
//        config.setIdGenerator(IdWorker::getIdStr);
//        HttpClientConfig httpClientConfig = new HttpClientConfig();
//        //连接超时
//        httpClientConfig.setConnectTimeout(10000);
//        //连接请求超时
//        httpClientConfig.setConnectionRequestTimeout(10000);
//        //双端建立socket连接
//        httpClientConfig.setSocketTimeout(10000);
//        //请求失败之后重试次数
//        httpClientConfig.setRequestRetryLimit(3);
//        config.setHttpClientConfig(httpClientConfig);
//        config.setKnowledgeBaseCacheLimit(200);
//        config.setProcessDefinitionCacheLimit(200);
//        return config;
//    }
//
//    @Override
//    public void configure(SpringProcessEngineConfiguration engineConfiguration) {
//        engineConfiguration.setActivityFontName("宋体");
//        engineConfiguration.setAnnotationFontName("宋体");
//        engineConfiguration.setLabelFontName("黑体");
//        engineConfiguration.setIdGenerator(IdWorker::getIdStr);
//    }
    @Bean
    public AsyncListenableTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(3);
        executor.setMaxPoolSize(3);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("hwsoft-flowable-task-Executor-");
        executor.setAwaitTerminationSeconds(30);
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAllowCoreThreadTimeOut(true);
        //调用者运行策略，线程池中没办法运行，那么就由提交任务的这个线程运行（哪儿来的回哪儿儿去~）
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }

    /**
     * BPM 模块的 ProcessEngineConfigurationConfigurer 实现类：
     * <p>
     * 1. 设置各种监听器
     * 2. 设置自定义的 ActivityBehaviorFactory 实现
     */
    @Bean
    public EngineConfigurationConfigurer<SpringProcessEngineConfiguration> bpmProcessEngineConfigurationConfigurer(
            ObjectProvider<FlowableEventListener> listeners) {
        return configuration -> {
            // 注册监听器，例如说 BpmActivityEventListener
            configuration.setEventListeners(ListUtil.toList(listeners.iterator()));
            // 定时器只有在异步执行器启用时才能触发,如果需要定时器，该配置项需要改为true
            configuration.setAsyncExecutorActivate(false);
            configuration.setActivityFontName("宋体");
            configuration.setAnnotationFontName("宋体");
            configuration.setLabelFontName("黑体");
            configuration.setIdGenerator(IdWorker::getIdStr);
        };
    }

    @Bean
    public TypeConverter typeConverter() {
        return new TypeConverterImpl();
    }

    /**
     * 在配置文件中如果没有字段，使用@Value的时候就会忽略掉，不会报错
     *
     * @return
     */
//    @Bean
//    public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
//        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
//        configurer.setIgnoreUnresolvablePlaceholders(true);
//        return configurer;
//    }
}
